#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include "serial.h"
#include "timer.h"
#define BUFFER_SIZE 8
#define RANGING_TIMES 10

void initialize(int baud_rate,int send_rate);
void  handle1();
void  handle2();
void  handle3();

int fd,recv_window,packet_all;
volatile int packet_recv,status,is_write,is_timeout;
unsigned char buffer_s[BUFFER_SIZE];
unsigned char buffer_r[BUFFER_SIZE];
fd_set rd;
struct timespec s,r,d; 

void   signal_handler_IO(void);


int main(int argc,char **argv)
{
    int nread,ret;
	unsigned int baud_rate=atoi(argv[1]);
	unsigned int send_rate=atoi(argv[2]);
	packet_all=send_rate*5;
	unsigned char count=0,i;

	initialize(baud_rate,send_rate);
	

	while(1){    	                 
		if(1==status){  
       		while((nread = read(fd,buffer_r,1)) > 0){
				for(i=0;i<nread;i++)
					packet_recv++;
			} 	    
		}                
  	}   
    close(fd);
    return ;
}

void initialize(int baud_rate,int send_rate)
{
	int ret;	  
	
	
  	if((fd = open_serial(fd,1)) < 0)
    {
        perror("open_serial error");
        exit(1);
    }

    if((ret=set_option(fd,baud_rate,8,'N',1)) < 0)
    {
        perror("set_option error");
        exit(1);
    }

	struct   sigaction   saio;  

	saio.sa_handler=signal_handler_IO;                
	sigemptyset(&saio.sa_mask);     
	saio.sa_flags=0;                
	saio.sa_restorer=NULL;             
	sigaction(SIGIO,&saio,NULL);        	  
	fcntl(fd,   F_SETOWN,   getpid());             
	fcntl(fd,   F_SETFL,   FASYNC); 	
 
	struct sigevent evp1,evp2;
	struct itimerspec ts1,ts2;
	timer_t timer1,timer2;

	evp1.sigev_value.sival_ptr = &timer1;
 	evp1.sigev_notify = SIGEV_SIGNAL;
	evp1.sigev_signo = SIGUSR1;
	signal(SIGUSR1, handle3);
 	
	ts1.it_interval.tv_sec = 0;
	ts1.it_interval.tv_nsec =50000*1000;
	ts1.it_value.tv_sec = 0;
	ts1.it_value.tv_nsec =50000*1000;

	if(ret= timer_create(CLOCK_REALTIME, &evp1, &timer1))
	{
		 perror("timer1 create error");
		 exit(1);
	}
	if(ret=timer_settime(timer1, 0, &ts1, NULL))
	{
		perror("timer1 settime error");
		exit(1);
	}


	int nread,times,first=1;
	struct timespec s1,s2;
	buffer_s[0]=RANGING_RESP;

	for(times=0;times<RANGING_TIMES;times++){
		status=0;
		is_timeout=0;
		ts1.it_interval.tv_sec = 0;
		ts1.it_interval.tv_nsec =50000*1000;
		ts1.it_value.tv_sec = 0;
		ts1.it_value.tv_nsec =50000*1000;
		while(first||!is_timeout){    				
			read(fd,buffer_r,1);
			clock_gettime(CLOCK_REALTIME, &r);
			if(1==status){ 
				first=0;
				status=0;      		
				if(RANGING_REQ==buffer_r[0]){   
					is_write=1;                            
					write(fd,buffer_s,1);	     
					buffer_r[0]=DATA;;
					printf("send&recv @:%dsec,%.1fuesc\n",r.tv_sec,r.tv_nsec/1000.0);          
				}
				break;   
    		}   //if        
  		}//while   
	}//for
	unsigned char send_buff[53];
	while(1){
		if(1==status){
		read(fd,buffer_r,1);
		if(TDMA_REQ==buffer_r[0])
		{
		// send data here
		printf("received request\n");
		send_buff[0]=TDMA_RESP;
		send_buff[1]=5;
		send_buff[2]=0;
		//write(fd,buffer_s,3);
		int send_data;
		
		for(send_data=3;send_data<53;send_data++)
			send_buff[send_data]=DATA; 
	
		write(fd,send_buff,53);
		}
		}
	}
	signal(SIGUSR1, handle1);

 	evp2.sigev_value.sival_ptr = &timer2;
 	evp2.sigev_notify = SIGEV_SIGNAL;
	evp2.sigev_signo = SIGUSR2;
	signal(SIGUSR2, handle2);

	ts1.it_interval.tv_sec = 1;
	ts1.it_interval.tv_nsec =0;
	ts1.it_value.tv_sec = 1;
	ts1.it_value.tv_nsec =0;

	ts2.it_interval.tv_sec = 5;
	ts2.it_interval.tv_nsec =0;
	ts2.it_value.tv_sec = 5;
	ts2.it_value.tv_nsec =0;

	/*
	if(ret= timer_create(CLOCK_REALTIME, &evp1, &timer1))
	{
		 perror("timer1 create error");
		 exit(1);
	}*/
	if(ret= timer_create(CLOCK_REALTIME, &evp2, &timer2))
	{
		 perror("timer2 create error");
		 exit(1);
	}		

	if(ret=timer_settime(timer1, 0, &ts1, NULL))
	{
		perror("timer1 settime error");
		exit(1);
	}
	if(ret=timer_settime(timer2, 0, &ts2, NULL))
	{
		perror("timer2 settime error");
		exit(1);
	}

	return ;
}

void  ranging(void)
{

}

void signal_handler_IO(void){                     
	if(!is_write){
		status=1;
	}  
	else
		is_write=0;	    	
} 

void  handle1()
{
 
}

void  handle2()
{
	if(packet_recv>=packet_all)
		packet_recv=packet_all;	
	printf("packet loss rate in last %d seconds:%.2f%\n",recv_window,100-(double)packet_recv*100.0/(double)packet_all);
	printf("recv:%d,all:%d\n",packet_recv,packet_all);
	packet_recv=0;
}

void  handle3()
{
	is_timeout=1;
}
